package com.friends.utils.tree;

import com.friends.utils.model.CityVO;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

/**
 * 构建树状结构工具类
 * @author Dark
 * @param <T> 结点类型
 */
public class TreeUtil<T extends CityVO> {
    /**
     * 两层循环实现建树
     *
     * @param treeNodes  传入的树节点列表
     * @param comparator
     * @return
     */
    public static <T extends CityVO> List<T> bulid(List<T> treeNodes, Object root, Comparator comparator) {

        List<T> trees = new ArrayList<T>();

        for (T treeNode : treeNodes) {
            // 判断是否为顶级结点
            if (root.equals(treeNode.getPid())) {
                trees.add(treeNode);
            }

            for (T it : treeNodes) {
                if (it.getPid().equals(treeNode.getId())) {
                    if (treeNode.getChildren() == null) {
                        treeNode.setChildren(new ArrayList<>());
                    }
                    // 放入子集
                    treeNode.add(it);
                }
            }
            if (comparator != null) {
                treeNode.getChildren().sort(comparator);
            }
        }
        return trees;
    }

    /**
     * 使用递归方法建树
     *
     * @param treeNodes
     * @return
     */
    public static <T extends CityVO> List<T> buildByRecursive(List<T> treeNodes, Object root) {
        List<T> trees = new ArrayList<T>();
        for (T treeNode : treeNodes) {
            if (root.equals(treeNode.getPid())) {
                trees.add(findChildren(treeNode, treeNodes));
            }
        }
        return trees;
    }

    /**
     * 递归查找子节点
     *
     * @param treeNodes
     * @return
     */
    public static <T extends CityVO> T findChildren(T treeNode, List<T> treeNodes) {
        for (T it : treeNodes) {
            if (treeNode.getId().equals(it.getPid())) {
                if (treeNode.getChildren() == null) {
                    treeNode.setChildren(new ArrayList<CityVO>());
                }
                // TODO 在这里可以计算数量
                treeNode.add(findChildren(it, treeNodes));
            }
        }
        return treeNode;
    }

    /**
     * 递归遍历子节点
     * @param treeNode
     * @param <T>
     * @return
     */
    public static <T extends CityVO> void listChildren(T treeNode, List<T> list) {
        List<T> children = treeNode.getChildren();
        if(children != null && !children.isEmpty()){
            children.parallelStream().forEach(node -> {
                listChildren(node,list);
            });
        }
        list.add(treeNode);
    }

}
